package com.aacar.op.service.security;

import com.google.common.collect.Lists;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;


public class SecUtils {
    private static Logger logger = LoggerFactory.getLogger(SecUtils.class);

    //===========apache shiro 相关 ==============//

    /**
     * 判断当前会话是否登录(没有登录)
     */
    public static boolean isAnonymous() {
        Subject currentUser = getSubject();
        if (currentUser == null) {
            return true;
        }
        if (!currentUser.isAuthenticated() && !currentUser.isRemembered()) {
            return true;
        }
        return false;
    }


    /**
     * 用户session中用户ID
     */
    public static Long getUserId() {
        ShiroUser u = getUser();
        return u != null ? u.getId() : null;
    }

    /**
     * 用户session中用户名
     */
    public static String getLoginName() {
        ShiroUser u = getUser();
        return u != null ? u.getLoginName() : null;
    }


    /**
     * 当前登录session对象
     *
     * @return
     */
    public static ShiroUser getUser() {
        Subject currentUser = getSubject();
        if (currentUser == null) {
            return null;
        }
        if (!(currentUser.getPrincipal() instanceof ShiroUser)) {
            return null;
        }
        ShiroUser principal = (ShiroUser) currentUser.getPrincipal();
        return principal;
    }

    public static Subject getSubject() {
        Subject currentUser = null;
        try {
            currentUser = org.apache.shiro.SecurityUtils.getSubject();
        } catch (UnavailableSecurityManagerException e) {
            //quite exception
            logger.warn("试图在初始化之前使用Shiro ");
        }
        return currentUser;
    }

    /**
     * 创建一个shiro的session,如果存在session就用现有的session，否则创建一个新的session
     *
     * @return {@link Session}
     */
    public static Session createSessionIfNull() {
        Session session = getSession();

        if (session == null) {
            session = getSession(true);
        }

        return session;
    }

    /**
     * 获取shiro的session
     *
     * @return {@link Session}
     */
    public static Session getSession() {
        return getSession(false);
    }

    /**
     * 获取shiro的session
     *
     * @param create true表示如果不存在，就创建，否则用现有的
     * @return {@link Session}
     */
    public static Session getSession(boolean create) {
        return org.apache.shiro.SecurityUtils.getSubject().getSession(create);
    }

    /**
     * 登录用户是否包含角色
     * <pre>
     *     if ( SystemVariables.hasRole( "admin" ) ) {
     *      log.info("呵呵,你有admin角色." );
     *     }
     * </pre>
     *
     * @param role 角色Code
     */
    public static boolean hasRole(String role) {
        return getSubject() != null && getSubject().hasRole(role);
    }

    public static boolean hasAllRoles(String... roles) {
        boolean hasAllRole = false;
        List<String> rolesColl = Lists.newArrayList(roles);
        Subject subject = getSubject();
        if (subject != null) {
            hasAllRole = subject.hasAllRoles(rolesColl);
        }
        return hasAllRole;
    }

    public static boolean hasAllRoles(List<String> roles) {
        boolean hasAllRole = false;
        Subject subject = getSubject();
        if (subject != null) {
            hasAllRole = subject.hasAllRoles(roles);
        }
        return hasAllRole;
    }

    public static boolean hasAnyRoles(String... roles) {
        List<String> roleList = Lists.newArrayList(roles);
        return hasAnyRoles(roleList);
    }

    public static boolean hasAnyRoles(List<String> roles) {
        boolean hasAnyRole = false;
        Subject subject = getSubject();
        if (subject != null) {
            for (String r : roles) {
                if (subject.hasRole(r.trim())) {
                    hasAnyRole = true;
                    break;
                }
            }
        }
        return hasAnyRole;
    }


    public static boolean hasPermission(String perm) {
        return getSubject() != null && getSubject().isPermitted(perm);
    }


    public static boolean hasAnyPermissions(String... perms) {
        boolean hasPerms = false;
        Subject subject = getSubject();
        if (subject != null) {
            for (String p : perms) {
                if (subject.isPermitted(p.trim())) {
                    hasPerms = true;
                    break;
                }
            }
        }
        return hasPerms;
    }

}
